﻿using Minecraft.Config;
using Minecraft.Config.Csv.CsvCls;
using Minecraft.Model;
using Minecraft.Model.Backpack;
using Minecraft.Model.ReqResp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Minecraft.ServerHall
{
	/// <summary>
	/// 背包物品操作相关
	/// </summary>
	public static class GoodsExt
	{
		/// <summary>
		/// 从配置中读取指定物品存放数量上限（获取指定itemId在格子中的最大存放数量（来自物品配置表））
		/// </summary>
		/// <param name="goodsItemId"></param>
		/// <returns></returns>
		public static int GetMaxCellNumConvert(this MinecraftSession session, string goodsItemId)
		{
			//Mod_Items mod_Items = CsvConfig.itemsList.FirstOrDefault(m => m.Id == goodsItemId);
			Mod_Items mod_Items = CsvConfig.GetMod_ItemsInfoById(goodsItemId);
			if (mod_Items == null)
			{
				//Mod_Blocks mod_Blocks = CsvConfig.blocksList.FirstOrDefault(m => m.Id == goodsItemId);
				Mod_BlockState mod_BlockState = CsvConfig.GetMod_BlockStateInfoById(goodsItemId);
				if (mod_BlockState == null)
				{
					throw new Exception($"mod_Items 物品配置表 物品信息不存在，请更新物品配置表，或者联系策划，或者该ItemId可能来自于方块配置表【goodsItemId：{goodsItemId}】");
				}
				else
				{
					return mod_BlockState.ItemMaxCount_Convert;
				}
			}
			else
			{
				return mod_Items.Max_num_Convert;
			}
		}

		public static bool IsExistItemsOrBlocks(this MinecraftSession session, string goodsItemId)
		{
			//Mod_Items mod_Items = CsvConfig.itemsList.FirstOrDefault(m => m.Id == goodsItemId);
			Mod_Items mod_Items = CsvConfig.GetMod_ItemsInfoById(goodsItemId);
			if (mod_Items == null)
			{
				//Mod_Blocks mod_Blocks = CsvConfig.blocksList.FirstOrDefault(m => m.Id == goodsItemId);
				Mod_BlockState mod_BlockState = CsvConfig.GetMod_BlockStateInfoById(goodsItemId);
				if (mod_BlockState == null)
				{
					return false;
				}
				else
				{
					return true;
				}
			}
			else
			{
				return true;
			}
		}
		/// <summary>
		/// 加载背包物品goodsItem信息（对物品格子进行占位模拟）
		/// </summary>
		/// <returns></returns>
		public static List<BackpackGoodsItemInfo> GetBackpackGoodsItemInfoList(this MinecraftSession session,
			EnumGoodsBelongsToType enumGoodsBelongsToType, string guid, out BaseResp baseResp)
		{
			baseResp = new BaseResp() { RespLevel = RespLevelEnum.Success, Msg = "" };
			//记录所有格子的position的存储情况
			var goodsList = session.minecraftSessionInfo.goodsList.GetBackpackGoodsCellInfo();
			//加载背包物品goodsItem信息
			List<BackpackGoodsItemInfo> goodsItemInfoList = new List<BackpackGoodsItemInfo>();

			//物品来源判断
			if (!MinecraftConfig.enumGoodsSourceBelongsToTypeList.Any(m => m == enumGoodsBelongsToType))
			{
				throw new Exception($"传入的类型错误【{enumGoodsBelongsToType.ToString()}】");
			}

			if (MinecraftConfig.bpShortbarBelongsToTypeList.Any(m => m == enumGoodsBelongsToType))
			{
				//循环 注意
				foreach (var belongsToType in MinecraftConfig.bpShortbarBelongsToTypeList)
				{
					var cellNum = 0;
					switch (belongsToType)
					{
						case EnumGoodsBelongsToType.ShortcutBar:
							{
								cellNum = MinecraftConfig.ShortcutBarCellInitNum;
							}
							break;
						case EnumGoodsBelongsToType.Backpack:
							{
								cellNum = session.minecraftSessionInfo.BackpackCellNum;
							}
							break;
						default:
							break;
					}
					var cellInfoList = goodsList.Where(m => m.enumGoodsBelongsToType == belongsToType && m.guid == guid).ToList();
					goodsItemInfoList.LoadGoodsItemInfo(cellInfoList, cellNum, belongsToType, guid);
				}
			}
			else
			{
				//-- 要做一个guid的信息存在判断，暂放（完成）

				switch (enumGoodsBelongsToType)
				{
					case EnumGoodsBelongsToType.FurnitureStorage:
						{
							var storageFurnitureInfo = session.minecraftSessionInfo.furnitureStorageList.FirstOrDefault(m => m.FurnitureId == guid);
							if (storageFurnitureInfo == null)
							{
								baseResp = new BaseResp() { RespLevel = RespLevelEnum.Error, Msg = $"传入的guid为【{guid}的存储家具数据库信息不存在】" };
								return null;
							}
							var mod_FurnitureInfo = storageFurnitureInfo.GetMod_FurnitureInfo();
							if (mod_FurnitureInfo == null)
							{
								baseResp = new BaseResp() { RespLevel = RespLevelEnum.Error, Msg = $"传入的guid为【{guid}的存储家具配置表信息不存在，数据异常】" };
								return null;
							}
							if (mod_FurnitureInfo.enumFurnitureType_Convert != EnumFurnitureType.Storage)
							{
								baseResp = new BaseResp() { RespLevel = RespLevelEnum.Error, Msg = $"传入的guid为【{guid}的家具类型不是存储家具类型】" };
								return null;
							}
							var cellInfoList = goodsList.Where(m => m.enumGoodsBelongsToType == enumGoodsBelongsToType && m.guid == guid).ToList();
							goodsItemInfoList.LoadGoodsItemInfo(cellInfoList, mod_FurnitureInfo.Store_Convert, enumGoodsBelongsToType, guid);
						}
						break;
					case EnumGoodsBelongsToType.Treasurebox:
						{
							if (guid.IsNullOrWhiteSpace())
							{
								baseResp = new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误（原因：guid 为空）" };
								return null;
							}
							var treasureBox = session.minecraftSessionInfo.furnitureTreasureBoxList.FirstOrDefault(m => m.FurnitureId == guid);
							if (treasureBox == null)
							{
								baseResp = new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误（原因：treasureBox 信息不存在）" };
								return null;
							}
							var map = session.minecraftSessionInfo.map;
							if (map.SourceMapId != treasureBox.TreasureBox_MapId)
							{
								baseResp = new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：玩家不出在当前地图，不允许操作）" };
								return null;
							}
							//var csvTreasureBox = CsvConfig.furnitureList.FirstOrDefault(m => m.Id == treasureBox.FurnitureItemId);
							var csvTreasureBox = CsvConfig.GetMod_DrawingInfoById(treasureBox.FurnitureItemId);
							var cellInfoList = goodsList.Where(m => m.enumGoodsBelongsToType == enumGoodsBelongsToType && m.guid == guid).ToList();
							goodsItemInfoList.LoadGoodsItemInfo(cellInfoList, csvTreasureBox.Store_Convert, enumGoodsBelongsToType, guid);
						}
						break;
					default:
						{
							baseResp = new BaseResp() { RespLevel = RespLevelEnum.Error, Msg = $"服务器错误，请在 MinecraftConfig.enumGoodsSourceBelongsToTypeList 常量中添加【{enumGoodsBelongsToType.ToString()}】元素" };
							return null;
						}
				}
			}

			goodsItemInfoList = (from itemInfo in goodsItemInfoList
								 orderby itemInfo.enumGoodsBelongsToType, itemInfo.GoodsPosition
								 select itemInfo).ToList();

			return goodsItemInfoList;
		}

		/// <summary>
		/// 加载背包物品goodsItem信息，格子补位操作
		/// </summary>
		/// <param name="backpackGoodsItemInfoList"></param>
		/// <param name="cellInfoList"></param>
		/// <param name="cellNum"></param>
		/// <param name="enumGoodsBelongsToType"></param>
		private static void LoadGoodsItemInfo(this List<BackpackGoodsItemInfo> backpackGoodsItemInfoList,
			List<BackpackCellInfo> cellInfoList, int cellNum, EnumGoodsBelongsToType enumGoodsBelongsToType, string guid)
		{
			for (int i = 0; i < cellNum; i++)
			{
				var backpackGoodsCellInfo = cellInfoList.FirstOrDefault(m => m.GoodsPosition == i);
				if (backpackGoodsCellInfo != null)
				{
					backpackGoodsItemInfoList.Add(new BackpackGoodsItemInfo
					{
						enumGoodsBelongsToType = backpackGoodsCellInfo.enumGoodsBelongsToType,
						GoodsPosition = i,
						GoodsItemId = backpackGoodsCellInfo.GoodsItemId,
						GoodsNum = backpackGoodsCellInfo.Num,
						guid = backpackGoodsCellInfo.guid,
					});
				}
				else
				{
					//如果找不到就占位
					backpackGoodsItemInfoList.Add(new BackpackGoodsItemInfo
					{
						enumGoodsBelongsToType = enumGoodsBelongsToType,
						GoodsPosition = i,
						GoodsItemId = "", //下面插入后，注意更新
						GoodsNum = 0,
						guid = guid,
					});
				}
			}
		}

		/// <summary>
		/// 背包物品结构的转换
		/// </summary>
		/// <param name="backpackGoodsList"></param>
		/// <returns></returns>
		public static List<BackpackCellInfo> GetBackpackGoodsCellInfo(this IEnumerable<GoodsModel> backpackGoodsList)
		{
			return backpackGoodsList.GroupBy(m => new { m.enumGoodsBelongsToType_Convert, m.GoodsPosition })
				.Select(g => new BackpackCellInfo()
				{
					enumGoodsBelongsToType = g.Key.enumGoodsBelongsToType_Convert,
					GoodsPosition = g.Key.GoodsPosition,
					GoodsItemId = g.First().GoodsItemId,
					GoodsId = g.First().GoodsId,
					Num = g.First().Num,
					WastageValue = g.First().WastageValue,
					guid = g.First().guid
				})
				.ToList();
		}


		/// <summary>
		/// 返回背包物品类型响应的状态（用于数据合法性验证：enumGoodsBelongsToType、goodsPosition）
		/// </summary>
		/// <param name="enumGoodsBelongsToType"></param>
		/// <param name="goodsPosition"></param>
		/// <param name="session"></param>
		/// <returns></returns>
		public static FurnitureBaseResp GetBackpackGoodsBelongsToTypeBaseType(this EnumGoodsBelongsToType enumGoodsBelongsToType,
			int goodsPosition, MinecraftSession session, string tips, string guid = "")
		{
			bool isFurniture = false;
			var timeNow = DateTimeOffset.Now;
			switch (enumGoodsBelongsToType)
			{
				case EnumGoodsBelongsToType.ShortcutBar:
					{
						if (goodsPosition < 0 || goodsPosition >= session.minecraftSessionInfo.ShortcutBarCellNum)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：GoodsPosition非法1【{tips}】）" };
						}
					}
					break;
				case EnumGoodsBelongsToType.Backpack:
					{
						if (goodsPosition < 0 || goodsPosition >= session.minecraftSessionInfo.BackpackCellNum)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：GoodsPosition非法2【{tips}】）" };
						}
					}
					break;
				case EnumGoodsBelongsToType.FurnitureStorage:
					{
						isFurniture = true;
						if (guid.IsNullOrWhiteSpace())
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：存储家具Id为空【{tips}】）" };
						}
						var furniture = session.minecraftSessionInfo.furnitureStorageList.FirstOrDefault(m => m.FurnitureId == guid);
						if (furniture == null)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：该存储家具信息不存在【传入的存储家具唯一id为{guid}】【{tips}】）" };
						}
						var Mod_FurnitureInfo = furniture.GetMod_FurnitureInfo();
						if (goodsPosition < 0 || goodsPosition >= Mod_FurnitureInfo.Store_Convert)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：GoodsPosition非法2，传入的goodsPosition小于0 或者 大于产出家具的itemId为【{furniture.FurnitureItemId}】的最大存储格子位置的上限值【{tips}】）" };
						}
					}
					break;
				case EnumGoodsBelongsToType.SurvivorEquipment:
					{
						if (guid.IsNullOrWhiteSpace())
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：幸存者Id为空【{tips}】）" };
						}
						var survivor = session.minecraftSessionInfo.survivorList.FirstOrDefault(m => m.SurvivorId.ToString() == guid);
						if (survivor == null)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：该幸存者信息不存在【传入的幸存者id为{guid}】【{tips}】）" };
						}
						//if (goodsPosition < 0 || goodsPosition >= MinecraftConfig.SurvivorCellInitNum)
						//{
						//	return new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误（原因：GoodsPosition非法2，传入的goodsPosition小于0 或者 大于幸存者的Id为【{survivor.SurvivorId}】的最大存储格子位置的上限值【{tips}】）" };
						//}
					}
					break;
				case EnumGoodsBelongsToType.Treasurebox:
					{
						isFurniture = true;
						if (guid.IsNullOrWhiteSpace())
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：幸存者Id为空【{tips}】）" };
						}
						var map = session.minecraftSessionInfo.map;
						var treasureBox = session.minecraftSessionInfo.furnitureTreasureBoxList.FirstOrDefault(m => m.FurnitureId == guid);
						if (treasureBox == null)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因： 当前地图 treasureBox 信息不存在）" };
						}
						//var csvTreasureBox = CsvConfig.furnitureList.FirstOrDefault(m => m.Id == treasureBox.FurnitureItemId);
						var csvTreasureBox = CsvConfig.GetMod_DrawingInfoById(treasureBox.FurnitureItemId);
						if (goodsPosition < 0 || goodsPosition >= csvTreasureBox.Store_Convert)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = $"错误（原因：GoodsPosition非法2，传入的goodsPosition小于0 或者 大于产出家具的itemId为【{treasureBox.FurnitureItemId}】的最大存储格子位置的上限值【{tips}】）" };
						}
					}
					break;
				case EnumGoodsBelongsToType.PlayerCorpse:
					{
						var timeSpanSeconds = Convert.ToInt32((DateTimeOffset.Now - session.minecraftSessionInfo.player.LastDeathTime).TotalSeconds);
						if (timeSpanSeconds > MinecraftConfig.CorpseDurationSeconds)
						{
							session.minecraftSessionInfo.goodsList.RemoveAll(m => m.enumGoodsBelongsToType_Convert == enumGoodsBelongsToType);
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = "错误3：（原因：尸体超时）" };
						}
					}
					break;
				case EnumGoodsBelongsToType.MonsterCorpseAndDismantleFurniture:
					{
						//合法性验证
						var dropInfo = session.minecraftSessionInfo.dropinfoList.FirstOrDefault(m => m.DropId.ToString() == guid);
						if (dropInfo == null)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = "错误3：（原因：dropInfo 不存在）" };
						}
						if (dropInfo.MapId != session.minecraftSessionInfo.map.SourceMapId)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = "错误3：（原因：dropInfo.MapId != map.SourceMapId）" };
						}
						//超时验证
						var seconds = Convert.ToInt32((timeNow - dropInfo.DropTime).TotalSeconds);
						if (seconds > MinecraftConfig.DismantleFurnitureBackpackSeconds)
						{
							return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, isFurniture = isFurniture, Msg = "错误3：（原因：已经超时）" };
						}
					}
					break;
				default:
					{
						return new FurnitureBaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误（原因：传入的物品类型不正确 或者暂不支持该物品类型，或者服务器程序漏掉了（GoodsExt.GetBackpackGoodsBelongsToTypeBaseType 方法）【enumGoodsBelongsToType：{enumGoodsBelongsToType}】【{tips}】）" };
					}
			}
			return new FurnitureBaseResp { RespLevel = RespLevelEnum.Success, isFurniture = isFurniture };
		}
	}
}
